package com.lee.treasure.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lee.starter.util.FileUtils;
import com.lee.treasure.entity.Columns;
import com.lee.treasure.mapper.ColumnsMapper;
import com.lee.treasure.service.IColumnsService;
import com.lee.treasure.vo.GenerateParams;
import com.lee.treasure.vo.GenerateVO;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lee
 * @since 2020-04-20
 */
@Service
public class ColumnsServiceImpl extends ServiceImpl<ColumnsMapper, Columns> implements IColumnsService {

    @Override
    public GenerateVO generate(GenerateParams params) {

        boolean wrap = params.getOptions().contains("wrap");

        GenerateVO generate = new GenerateVO();
        generate.setSelects(new ArrayList<>());
        generate.setSelectsAs(new ArrayList<>());
        generate.setTables(new ArrayList<>());

        params.getTables().forEach(table -> {
            List<Columns> columns = lambdaQuery()
                    .eq(Columns::getTableSchema, params.getDb())
                    .eq(Columns::getTableName, table)
                    .list();

            generate.getTables().add(table);
            generate.getSelects().add(buildSelect(columns, wrap));
            generate.getSelectsAs().add(buildSelectAs(columns, table, wrap));
        });

        if (params.getTables().size() > 1) {
            buildJoin(generate);
        }
        return generate;
    }

    private String buildSelect(List<Columns> columns, boolean wrap) {
        StringBuilder selects = new StringBuilder();
        columns.forEach(c -> {
            selects.append("`").append(c.getColumnName()).append("`,").append(wrap ? "\r\n" : "");
        });
        return selects.substring(0, selects.lastIndexOf(","));
    }

    private String buildSelectAs(List<Columns> columns, String table, boolean wrap) {
        StringBuilder selectsAs = new StringBuilder();
        columns.forEach(c -> {
            selectsAs.append("`").append(c.getColumnName()).append("` as `")
                    .append(table).append("_").append(c.getColumnName()).append("`,").append(wrap ? "\r\n" : "");
        });
        return selectsAs.substring(0, selectsAs.lastIndexOf(","));
    }

    private void buildJoin(GenerateVO generate) {

        List<String> selects = generate.getSelects();

        String template = null;
        try {
            template = FileUtils.txt2String(ResourceUtils.getFile("classpath:template/mapper.txt"));
        } catch (FileNotFoundException e) {
            return;
        }

        StringBuilder select = new StringBuilder();
        StringBuilder map = new StringBuilder();

        for (int i = 0; i < selects.size(); i++) {
            String table = generate.getTables().get(i);

            String s = selects.get(i);
            String[] cols = s.split(",");
            if (i > 0) {
                map.append("<association property=\"?\" javaType=\"?\">\r\n");
            }
            for (String col : cols) {
                col = col.replace("`","");
                String as = table + "_" + col;
                select.append(table).append(".").append(col).append(" as ").append(as).append(",").append("\r\n");
                String key = StringUtils.underlineToCamel(col);
                if ("id".equals(key)) {
                    map.append("<id property=\"id\" column=\"").append(as).append("\"/>\r\n");
                } else {
                    map.append("<result property=\"").append(key).append("\" column=\"").append(as).append("\"/>\r\n");
                }
            }
            if (i > 0) {
                map.append("</association>\r\n");
            }
        }
        template = template.replace("{#select}", select.substring(0, select.lastIndexOf(",")) + "\r\n");
        template = template.replace("{#leftTable}", generate.getTables().get(0));
        template = template.replace("{#map}", map.toString());


        StringBuilder join = new StringBuilder();
        for (int i = 1; i < generate.getTables().size(); i++) {
            join.append("LEFT JOIN ").append(generate.getTables().get(i)).append(" ON ")
                    .append(generate.getTables().get(0)).append(".?  = ")
                    .append(generate.getTables().get(i)).append(".?\r\n");
        }
        template = template.replace("{#join}", join.toString());

        System.out.println(template);
        generate.setJoin(template);
    }
}
